package com.jjtm.common.core.utils.security;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.SecureRandom;

/**
 * @author wangbaofeng
 */
public class Encodes {

    /**
     * 随机字符集合
     */
    private static String NONCE_STRING = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    /**
     * 安全的随机数生成器
     */
    private static SecureRandom random = new SecureRandom();

    /**
     * 密码salt字节数组长度
     */
    private static int SALT_SIZE = 8;

    /**
     * 密码加密类型
     */
    public static final String PASSWORD_ALGORITHM = "SHA-1";

    /**
     * 密码散列次数
     */
    public static int PASSWORD_INTERATIONS = 1024;

    /**
     * 对字符串进行MD5加密
     *
     * @param message message
     * @return String
     */
    public static String md5(String message) {
        return DigestUtils.md5Hex(message);
    }

    /**
     * 对字节数组进行MD5加密
     *
     * @param data data
     * @return String
     */
    public static String md5(byte[] data) {
        return DigestUtils.md5Hex(data);
    }

    /**
     * 对字符串进行简单的SHA1加密
     *
     * @param message message
     * @return String
     */
    public static String sha1(String message) {
        return DigestUtils.sha1Hex(message);
    }

    /**
     * 对字节数组进行简单的SHA1加密
     *
     * @param message message
     * @return byte[]
     */
    public static byte[] sha1(byte[] message) {
        return DigestUtils.sha1(message);
    }

    /**
     * 对字符串进行简单的SHA256加密
     *
     * @param message message
     * @return String
     */
    public static String sha256(String message) {
        return DigestUtils.sha256Hex(message);
    }

    public static String sha256_mac(String message, String key) {
        String outPut = null;
        try {
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            byte[] bytes = sha256_HMAC.doFinal(message.getBytes());
            outPut = byteArrayToHexString(bytes);
        } catch (Exception e) {
            System.out.println("Error HmacSHA256========" + e.getMessage());
        }
        return outPut;
    }

    public static String byteArrayToHexString(byte[] b) {
        StringBuilder sb = new StringBuilder();
        String stmp;
        for (int n = 0; b != null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1) {
                sb.append('0');
            }

            sb.append(stmp);
        }
        return sb.toString().toLowerCase();
    }

    /**
     * 对字节数组进行简单的SHA256加密
     *
     * @param message message
     * @return byte[]
     */
    public static byte[] sha256(byte[] message) {
        return DigestUtils.sha256(message);
    }

    /**
     * Hex编码
     *
     * @param data data
     * @return String
     */
    public static String hexEncode(byte[] data) {
        return Hex.encodeHexString(data);
    }

    /**
     * Hex解码
     *
     * @param message message
     * @return String
     */
    public static byte[] hexDecode(String message) {
        byte[] result = null;
        try {
            result = Hex.decodeHex(message.toCharArray());
        } catch (DecoderException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 生成随机salt
     *
     * @return String
     */
    public static String salt() {
        byte[] bytes = new byte[SALT_SIZE];
        random.nextBytes(bytes);
        return hexEncode(bytes);
    }

    /**
     * 生成安全密码
     *
     * @param password 源数据
     * @param salt     加盐
     * @return String
     */
    public static String password(String password, String salt) {
        MessageDigest digest = DigestUtils.getSha1Digest();
        digest.update(hexDecode(salt));

        byte[] result = digest.digest(password.getBytes());

        for (int i = 1; i < PASSWORD_INTERATIONS; i++) {
            digest.reset();
            result = digest.digest(result);
        }

        return Hex.encodeHexString(result);
    }

    /**
     * 获取随机字符串
     *
     * @param length 字符串长度
     * @return String
     */
    public static String nonceString(Integer length) {
        int index;
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            index = random.nextInt(62);
            sb.append(NONCE_STRING.charAt(index));
        }
        return sb.toString();
    }

}
